/**
 * 防抖
 * 防抖函数确保在某个连续事件触发后的一段时间内只执行一次函数。如果在这段时间内再次触发事件，计时器会被重新启动，从而延迟函数的执行。
 * @author Wang LiZhi
 * @param func 执行的函数
 * @param delay {number} 多长时间内发生，只执行最后一次
 * */
// export function debounce(func: Function, delay: number) {
//   let timer: unknown;
//   return function () {
//     const context:unknown = this as unknown;
//     const args = arguments;
//     if (timer) clearTimeout(timer);
//     timer = setTimeout(() => {
//       func.apply(context, args);
//     }, delay);
//   };
// }
type Func = (...args: unknown[]) => void;
export function debounce<T extends (...args: unknown[]) => unknown>(
  func: T,
  delay: number
): (...args: Parameters<T>) => void {
  let timer: NodeJS.Timeout | null = null;

  return function (this, ...args): unknown {
    const context = this;

    if (timer) {
      clearTimeout(timer);
      timer = null;
    }

    timer = setTimeout((): unknown => {
      func.apply(context, args);
      clearTimeout(timer);
      timer = null;
    }, delay);
  };
}

/**
 * 节流
 * 节流函数确保在一段时间内，不论事件触发多少次，函数只会被执行一次。它会在固定的时间间隔内触发函数。
 * @author Wang LiZhi
 * @param func 要节流执行的函数
 * @param delay {number} 多长时间内执行一次
 * */
export function throttle(func: Function, delay: number) {
  let lastTime = 0;
  return function (): void {
    const currentTime = new Date().getTime();
    if (currentTime - lastTime >= delay) {
      func.apply(this, arguments);
      lastTime = currentTime;
    }
  };
}

/**
 * 柯里化函数
 * 柯里化（Currying）是一种函数式编程技术，它将一个接受多个参数的函数转化为一系列只接受一个参数的函数。柯里化可以让函数更灵活，方便组合和重用。
 * @author Wang LiZhi
 * @param {Function} func
 * @returns {Function | unknown}
 */
export function curry(func: Func) {
  const length = func.length;
  function curried(...args: unknown[]): unknown {
    if (args.length === length) {
      return func(...args);
    } else {
      return function (...moreArgs: unknown[]): unknown {
        return curried(...args, ...moreArgs);
      };
    }
  }
  return curried;
}

export function sleep(time: number): Promise<unknown> {
  return new Promise((resolve: Func): void => {
    setTimeout(resolve, time);
  });
}

export function clocker(callback = () => {}, time: number) {
  let count = time;
  const timer = setInterval(() => {
    if (count === 0) {
      clearInterval(timer);
      callback(true);
      return;
    }
    callback();
    count -= 1;
  }, 1000);
  return () => {
    clearInterval(timer);
  };
}




export function scaleObjectValues(target) {
  return Object.entries(target).reduce((acc, [key, value]) => {
    return {
      ...acc,
      [key]: value* 1000
    }
  },{})
}